
#include "Simple_window.h"
#include "Graph.h"
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Text_Display.H>

#include "Store_menu.h"
#include <iostream>
#include "DisplayRBJ.h"
#include "ExtraCreditRBJ.h"


using namespace std;
using namespace Store;
using namespace Graph_lib;

//types we need

namespace Graph_lib {
//------------------------------------------------------------------------------
	struct Window_text_display : Widget {
		Window_text_display(Point XY, int W, int H, string L, Callback cb): Widget(XY, W, H, L, cb)
		{}
		void set_buffer(string s);
		void attach(Window&);
	private:
		Fl_Text_Buffer data;
		Fl_Text_Display *ptd;

	};
	void Window_text_display::attach(Window& win)
	{
		ptd = new Fl_Text_Display(loc.x, loc.y, width, height, label.c_str());
		ptd->buffer(&data);
		pw  = (Fl_Widget*) ptd;
		pw->callback(reinterpret_cast<Fl_Callback*>(do_it), &win); // pass the window
		own = &win;
	}
	void Window_text_display::set_buffer(string s) 
	{
		data.text(s.c_str());
	}

//------------------------------------------------------------------------------
	struct Menu_bar : Widget {
		Menu_bar(Point XY, int W, int H, Callback cb): Widget(XY, W, H, "", cb)
		{}
		void menu(Fl_Menu_Item *ma);
		void attach(Window&);
	private:
		Fl_Menu_Bar *pmb;
		Fl_Menu_Item *ma;

	};
	void Menu_bar::attach(Window& win)
	{
		pmb = new Fl_Menu_Bar(loc.x, loc.y, width, height);
		pmb->menu(ma);
		pw  = (Fl_Widget*) pmb;
		pw->callback(reinterpret_cast<Fl_Callback*>(do_it), &win); // pass the window
		own = &win;
	}
	void Menu_bar::menu(Fl_Menu_Item *m) 
	{
		ma = m;
	}
}

//header declarations
void do_graph_box(Graph_lib::Window&);
//RBJ added cat box
void do_graph_cat_box(Graph_lib::Window&);
void do_about_box(Graph_lib::Window&);
void do_read(Graph_lib::Window&, Store_menu&, string, string, Msg_type);
//VCN do_help_box added
void do_help_box(Graph_lib::Window&);
void do_displays_box(Msg_type type, Graph_lib::Window& w);
void do_custs_graph(Graph_lib::Window& w);
//!!! Rendy added new do_save
void do_save(Graph_lib::Window&, Store_menu&, string, string, Msg_type);
void Main_Window_CB(Fl_Widget*, void*);
void Menu_Bar_CB (Fl_Widget*, void*);

//global data
bool main_window_click = false;
bool menu_bar_click = false;
bool main_click_enabled = true;//force serialization on clicks
int window_userdata;

//main window menu bar
//Note: for expediancy sake to define the menu bar below we used an FLTK type Fl_Menu_Item. 
//This makes our program  directly depend on FLTK instead of our interface Graph_lib.
//We don't like this, but we did it to save time, which often happens in the real world.
//A better solution is to write code to hide this in the implementation of our Graph_lib::Menu_bar
//An interesting exercise is to see if you can eliminate direct references in our code to FLTK types 
Fl_Menu_Item menu_bar[] = {
 {"Read", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Customers", 0,  (Fl_Callback*)Main_Window_CB, Address (Read_customers), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Carts", 0,  (Fl_Callback*)Main_Window_CB, Address (Read_carts), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Category/Products", 0,  (Fl_Callback*)Main_Window_CB, Address (Read_category_products), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {"Show", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Categories", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_categories), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Customers", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_customers), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Products", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_products), 0, FL_NORMAL_LABEL, 0, 14, 0},
 //VCN added Carts and Cart Items to the Show menu
 {"Carts", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_carts), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Cart Items", 0,  (Fl_Callback*)Main_Window_CB, Address (Show_cart_items), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {"Find", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Category Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Find_category_sales), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Customer Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Find_customer_sales), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Product Sales", 0,  (Fl_Callback*)Main_Window_CB, Address (Find_product_sales), 0, FL_NORMAL_LABEL, 0, 14, 0},
 
 //VCN.B
 {"Top Cart", 0,  (Fl_Callback*)Main_Window_CB, Address (Toprev_button), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Top Products", 0,  (Fl_Callback*)Main_Window_CB, Address (Display_products), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Top Customers", 0,  (Fl_Callback*)Main_Window_CB, Address (Display_customers), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {"Update", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Add Cart Item", 0,  (Fl_Callback*)Main_Window_CB, Address (Update_add_cart_item), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Add Product", 0,  (Fl_Callback*)Main_Window_CB, Address (Update_add_product), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Add Customer", 0,  (Fl_Callback*)Main_Window_CB, Address (Update_add_customer), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 //VCN C.1
 {"Graph", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Cart Sales Per Month", 0,  (Fl_Callback*)Main_Window_CB, Address (Graph_carts), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Sales Per Customer", 0,  (Fl_Callback*)Main_Window_CB, Address (Graph_custs), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Category Sales Per Month", 0,  (Fl_Callback*)Main_Window_CB, Address (Graph_categories), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {"About", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Info", 0,  (Fl_Callback*)Main_Window_CB, Address (About_info), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Help", 0,  (Fl_Callback*)Main_Window_CB, Address (About_help), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {"Exit", 0,  0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0},
 {"Save and exit", 0,  (Fl_Callback*)Main_Window_CB, Address (Exit_program), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {"Exit", 0,  (Fl_Callback*)Main_Window_CB, Address (Exit_without_save), 0, FL_NORMAL_LABEL, 0, 14, 0},
 {0,0,0,0,0,0,0,0,0},
 {0,0,0,0,0,0,0,0,0}
};


//call back functions
void cust_cb(Address addr, Address) // callback for customer button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Customers_button));
}
void cart_cb(Address addr, Address) // callback for customer button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Carts_button));
}
void cat_cb(Address addr, Address) // callback for customer button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Categories_button));
}
void prod_cb(Address addr, Address) // callback for customer button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Products_button));
}
void cart_items_cb(Address addr, Address) // callback for customer button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Cart_items_button));
}
//RBJ added new callback
void toprev_cb(Address addr, Address) // callback for customer button
{
	Main_Window_CB((Fl_Widget*) addr, Address (Toprev_button));
}

 void display_cb(Address addr, Address) // callback for display window
{
	Main_Window_CB((Fl_Widget*) addr, Address (Display_window));
}
 void menu_bar_cb(Address addr, Address)//callback for menu bar
 {
	 Menu_Bar_CB((Fl_Widget*) addr, Address (Menu_bar_cb));
 }

void Menu_Bar_CB (Fl_Widget*, void* ud) {
	cout << "Menu Bar Callback" << " Userdata=" << (int) ud << "\n";
	menu_bar_click = true;
}

void Main_Window_CB(Fl_Widget*, void* ud) {
	if(main_click_enabled)//don't signal the window click if main loop is active
	{
		cout << "Main Window Callback" << " Userdata=" << (int) ud << "\n";
		window_userdata = (int) ud;
		main_window_click = true;
		main_click_enabled = false; //main loop active on current click
	}
}
//wait functions for callbacks to be executed
void wait_for_main_window_click() {
	while (!main_window_click) 
		Fl::wait();
	main_window_click = false;
	Fl::redraw();
}

void wait_for_menu_bar_click() {
	while (!menu_bar_click)
		Fl::wait();
	menu_bar_click = false;
	Fl::redraw();
}

Store_menu m;

int main()
{
	//create the main window and display it
    Graph_lib::Window sw(600, 500, "OnLine Store Report Program");
    Button cust(Point(40, 50), 100, 30, "Customers", cust_cb);
	sw.attach(cust);
	Button cart(Point(40, 100), 100, 30, "Carts", cart_cb);
	sw.attach(cart);
	Button cat(Point(40, 150), 100, 30, "Categories", cat_cb);
	sw.attach(cat);
	Button prod(Point(40, 200), 100, 30, "Products", prod_cb);
	sw.attach(prod);
	Button cart_items(Point(40, 250), 100, 30, "Cart Items", cart_items_cb);
	sw.attach(cart_items);
	/*/RBJ add new button
	Button toprev(Point(40, 300), 100, 30, "Top Cart", toprev_cb);
	sw.attach(toprev);*/
    sw.callback((Fl_Callback*)Main_Window_CB, Address (Exit_program));
	Menu_bar mb(Point(0, 0), 600, 30, menu_bar_cb);
    mb.menu(menu_bar);
	sw.attach(mb);

	Window_text_display t(Point(150,50),400, 400, "Data Display", display_cb );
	t.set_buffer("No Data Loaded\n");
	sw.attach(t);
 	sw.resizable(&sw);
	
	DisplayNJG d;


	//main loop to execute user clicks on the main window
	try {
		
		while(true) {
			main_click_enabled = true;
			wait_for_main_window_click();
			cout << "Act on userdata = " << window_userdata << endl;
			switch(window_userdata) 
			{
				//need to complete all the menu cases
				case Read_customers:
					do_read(sw, m, "cust.dat", "Open Customer File", Read_customers);
					break;
				case Read_carts:
					do_read(sw, m, "carts.dat", "Open Carts Data File", Read_carts);
					break;
				case Read_category_products:
					do_read(sw, m, "catprd.dat", "Open Catelog/Product File", Read_category_products);
					break;
				case About_info:
					do_about_box(sw);
					break;
				//VCN cases added
				case About_help:
					do_help_box(sw);
					break;
				case Show_customers:
					t.set_buffer(m.show_customers().c_str());
					break;
				case Show_products:
					t.set_buffer(m.show_products().c_str());
					break;
				case Show_categories:
					t.set_buffer(m.show_categories().c_str());
					break;
				case Show_carts:
					t.set_buffer(m.show_carts().c_str());
					break;
				case Show_cart_items: 
					t.set_buffer(m.show_cart_items().c_str());
					break;
				//RBJ added Part B.1 //NJG added Part B.2 //VCN.B3
				case Toprev_button: case Display_products: case Display_customers:
					do_displays_box((Msg_type) window_userdata,sw);
					break;
				//VCN C.3
				case Graph_custs:
					do_custs_graph(sw);
					break;
				case Graph_carts:
					do_graph_box(sw);
					break;
				case Customers_button: case Carts_button: case Categories_button: case Cart_items_button: case Products_button:
					t.set_buffer(m.show_button((Msg_type) window_userdata).c_str());
					break;
				case Graph_categories:
					do_graph_cat_box(sw);
					break;
				case Exit_program:
					//!!! Rendy's part starts here. Save all data and then exit
					do_save(sw, m, "cust.dat", "Save Customer File", Save_customers);
					do_save(sw, m, "carts.dat", "Save Carts Data File", Save_carts);
					do_save(sw, m, "catprd.dat", "Save Category/Product File", Save_category_products);
					cout << "save files and exit\n";
					exit(0); //exit program
					break;
				case Exit_without_save:
					cout << "exit\n";
					exit(0); //exit program
					break;
				default:
					cout << "case not implemented\n";
			}
		}
		return 0;
	}
	catch(exception& e) {
		cerr << "exception: " << e.what() << '\n';
		return 1;
	}
	catch (...) {
		cerr << "Some exception\n";
		return 2;
	}
}
//show about box info window
void do_about_box(Graph_lib::Window& w) 
{
	//!!! Rendy's part starts here. It shows team's data and each member's data
	Graph_lib::Window ab(Point(w.x()+100, w.y()+100), 800, 400, "About Maroon 567-17");
	ab.color(Color::white);
	ab.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_about_box));
	Image vincent(Point(70,100),"Vincent_resize.jpg");
	ab.attach(vincent);
	Image rendy(Point(310,100),"Rendy_resize.jpg");
	ab.attach(rendy);	
	Image nick(Point(550,100),"Nick_resize.jpg");
	ab.attach(nick);
	
	Text teamdata(Point(70,50), "OLES GUI - Maroon 567-17 Team");
	teamdata.set_color(Color::black);
	ab.attach(teamdata);

	Text vincentdata(Point(70,350), "Vincent Nguyen - TAMU");
	vincentdata.set_color(Color::black);
	ab.attach(vincentdata);
	
	Text rendydata(Point(310,350), "Rendy Bambang J. - ITB");
	rendydata.set_color(Color::black);
	ab.attach(rendydata);

	Text nickdata(Point(550,350), "Nick Giunta - TAMU");
	nickdata.set_color(Color::black);
	ab.attach(nickdata);

	wait_for_menu_bar_click();
	
	//clean up window
	ab.detach(vincent);
	ab.detach(rendy);
	ab.detach(nick);
	ab.detach(teamdata);
	ab.detach(vincentdata);
	ab.detach(rendydata);
	ab.detach(nickdata);
	return;
}

//VCN show help box info window
void do_help_box(Graph_lib::Window& w)
{
	Graph_lib::Window ab(Point(w.x()+100, w.y()+100), 500, 300, "Help Box");
	ab.color(Color::white);
	ab.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_help_box));
	
	Window_text_display text_box(Point(0,0),500, 300, "", display_cb );
	text_box.set_buffer("No Data Loaded\n");
	ab.attach(text_box);
	
	string text;
	text+="--------------------------------\n";
	text+="   Online Store Program Help\n";
	text+="--------------------------------\n";
	text+="Use the mouse to navigate and click.\n"; 
	text+="Choose an option from the menu bar or the main screen\n";
	text+="Menu Bar\n";
	text+="Read: Choose a file to read from to input data\n";
	text+="Show: Choose a category to display data from\n";
	text+="Find: Do searches for certain categories\n";
	text+="Update: Update the categories\n";
	text+="Exit:  Exit\n";
	text_box.set_buffer(text);
	wait_for_menu_bar_click();
	ab.detach(text_box);//clean up window
	return;
}

void do_custs_graph(Graph_lib::Window& w)
{

	vector<CustTotal> ct=GraphingVCN::graph_display();
	stringstream xlabel;
	xlabel<<"Customers       ";
	for(int i=0; i<ct.size(); i++)
	{
		xlabel<<left<<setw(11)<<ct[i].getCust().getCustName();
	}
	
	Graph_lib::Window ab(Point(w.x()+100, w.y()+100), (xlabel.str().size()+50)*5, 700, "Graphical Display");
	ab.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_displays_box));
	
	if(!ct.size()==0)
	{
	
	const int xmax(xlabel.str().size()*6), ymax(600), xoffset(100), yoffset(30), xspace(40), yspace(40), xlength(xmax-xoffset-xspace), ylength(ymax-yoffset-yspace);
	const double xscale(double(xlength)/(ct.size())), yscale(double(ylength)/(ct.front().getTot()));
	
	Axis x(Axis::x, Point(xoffset,ymax-yoffset), xlength, ct.size(), xlabel.str());
	x.label.move(-275,0);
	Axis y(Axis::y, Point(xoffset,ymax-yoffset), ylength,10,"Total Customer Sales");
	y.label.move(0,-5);
	x.label.set_color(Color::black);
	y.label.set_color(Color::black);
	
	
	
	
	stringstream cust_tots;
	for(int i=0; i<ct.size(); i++)
	{
		
		cust_tots<<"$"<<left<<setw(10.5)<<ct[i].getTot();
	}
	Text tots(Point(xoffset+12,yoffset+ylength-10),cust_tots.str());
	tots.set_color(Color::black);
	
	int k=0;
	vector<Graph_lib::Rectangle*> rects;
	for(int j=0; j<ct.size(); j++)
	{
		Graph_lib::Rectangle *rect;
		
		rect = new Graph_lib::Rectangle(Point(xoffset+j*(xscale+4),yoffset+ylength-yscale*ct[j].getTot()), xscale+4, yscale*(ct[j].getTot()+600));
		if (k==0){
		rect->set_fill_color(Color::blue);
		k=1;
		}
		else if(k==1){
		rect->set_fill_color(Color::cyan);
		k=0;
		}
		rects.push_back(rect);
	}
	
	for(int i=0; i<rects.size(); i++)
	{
		ab.attach(*rects[i]);
	}
	
	ab.attach(x);
	ab.attach(y);

	ab.attach(tots);
	
	wait_for_menu_bar_click();
	
	for(int i=0; i<rects.size(); i++)
	{
		ab.detach(*rects[i]);
	}
	ab.detach(x);
	ab.detach(y);

	ab.detach(tots);
	}
	else{wait_for_menu_bar_click();}
}

//NJG C.2
void do_graph_box(Graph_lib::Window& w){
	Graph_lib::Window ab(Point(w.x()+100, w.y()+100), 500, 300, "Graphical Display");
	ab.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_displays_box));
	vector<double>total=GraphingNJG::graph_display();
	vector<double>sorted=total;
	sort (sorted.begin(), sorted.end());
	const int xmax(500), ymax(300), xoffset(50), yoffset(30), xspace(40), yspace(40), xlength(xmax-xoffset-xspace), ylength(ymax-yoffset-yspace), start_month(1), end_month(12);
	const double xscale(double(xlength)/(end_month)), yscale(double(ylength)/(sorted.back()));
	Axis x(Axis::x, Point(xoffset,ymax-yoffset), xlength, end_month, "Month Jan  Feb   Mar    Apr   May    Jun    Jul    Aug   Sep   Oct   Nov   Dec");
	x.label.move(-135,0);
	Axis y(Axis::y, Point(xoffset,ymax-yoffset), ylength,10,"Total cart sales");
	y.label.move(0,-10);
	stringstream bar_label;
	for (int i(0);i<total.size();++i)
	{
		bar_label << "$" << total[i] << setw(3);
	}
	Text t (Point(xoffset+5,yoffset+5),bar_label.str());
	t.set_font_size(8);
	Graph_lib::Rectangle* rect;
	vector<Graph_lib::Rectangle*> rects;
	for(int i(0);i<total.size();++i)
	{
		int x=xoffset+(1+i-start_month)*xscale;
		int y=ymax-yoffset+total[i]*-yscale;
		rect = new Graph_lib::Rectangle(Point(x,y),Point(xoffset+(1+i)*xscale,ymax-yoffset));
		if (i%2==0) rect->set_fill_color(Graph_lib::Color::black);
		else rect->set_fill_color(Graph_lib::Color::red);
		rects.push_back(rect);
	}
	for(int i(0);i<rects.size();++i) ab.attach(*rects[i]);
	ab.attach(x);
	ab.attach(y);
	ab.attach(t);
	wait_for_menu_bar_click();
	for(int i(0);i<rects.size();++i) ab.detach(*rects[i]);
	ab.detach(x);
	ab.detach(y);
	ab.detach(t);
}

void do_displays_box(Msg_type type, Graph_lib::Window& w)
{
	Graph_lib::Window ab(Point(w.x()+100, w.y()+100), 500, 300, "Display");
	ab.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_displays_box));
	
	Window_text_display text_box(Point(0,0),500, 300, "", display_cb );
	text_box.set_buffer("No Data Loaded\n");
	ab.attach(text_box);
	
	DisplayNJG d;
	switch(type)
	{
		//RBJ added Part B.1
				case Toprev_button:
					cout << "Checking all carts takes sometime. Please wait...\n";
					text_box.set_buffer(DisplayRBJ::display(m).c_str());
					break;
				//NJG added Part B.2
				case Display_products:
					text_box.set_buffer(d.display().c_str());
					break;
				//VCN.B3
				case Display_customers:
					text_box.set_buffer(DisplayVCN::display_customers().c_str());
					break;
	}
	wait_for_menu_bar_click();
	ab.detach(text_box);
}

void do_read(Graph_lib::Window& w, Store_menu& m, string dfn, string msg, Msg_type type)
{
	//Here again we tied our code directly to the FLTK library instead of creating an interface in our Graph_lib interface to FLTK
	//We did it for lack of time, which reflects the real word. Unfortunately if we wanted to move our code to a different graphics
	//library, we have to change our code and not just our Graphic_lib implementation.
	Fl_File_Chooser fc(dfn.c_str(), "*.dat", Fl_File_Chooser::CREATE, msg.c_str());
	fc.show();
	while (fc.shown())
		Fl::wait();	//wait for OK or Cancel button
	if(0!=fc.value())//make sure there is a string to use as a filename
	{
		string fname = fc.value();
		switch(type) {
			case Read_customers:
				m.read_custs(fname);
				break;
			case Read_carts:
				m.read_carts(fname);
				break;
			case Read_category_products:
				m.read_catprds(fname);
				break;
			default:
				throw InvalidType();
		}
	}
	return;
}

//!!! Rendy added a new function to save data
void do_save(Graph_lib::Window& w, Store_menu& m, string dfn, string msg, Msg_type type)
{
	//Here again we tied our code directly to the FLTK library instead of creating an interface in our Graph_lib interface to FLTK
	//We did it for lack of time, which reflects the real word. Unfortunately if we wanted to move our code to a different graphics
	//library, we have to change our code and not just our Graphic_lib implementation.
	Fl_File_Chooser fc(dfn.c_str(), "*.dat", Fl_File_Chooser::CREATE, msg.c_str());
	fc.show();
	while (fc.shown())
		Fl::wait();	//wait for OK or Cancel button
	if(0!=fc.value())//make sure there is a string to use as a filename
	{
		string fname = fc.value();
		switch(type) {
			case Save_customers:
				m.save_custs(fname);
				break;
			case Save_carts:
				m.save_carts(fname);
				break;
			case Save_category_products:
				m.save_catprds(fname);
				break;
			default:
				throw InvalidType();
		}
	}	
	return;
}


Color get_color(int x){
	bool notfound = true;
	int i = 0;
	while(notfound && i<m.get_cats().size()){
		if(m.get_cats()[i].getCatId() == x)
			notfound = false;					
		i++;
	}
	i--;
	if(i<=13){
		return ((Color::Color_type) i);
	} else {
		int offset = 255/(20-14);
		return Color::Color((i-13)*offset);
	}
}

//RBJ Part C
void do_graph_cat_box(Graph_lib::Window& w){
	Graph_lib::Window cat_box(Point(w.x(), w.y()), 650, 700, "Category Sales per Month");
	cat_box.callback((Fl_Callback*)Menu_Bar_CB, Address (Close_displays_box));
	
	vector<vector<Cat_Percent> > cat_sales = ExtraCreditRBJ::graph_display();	
	
	int baroffset_x = 50, baroffset_y, barwidth = 30, barmaxheight = 400, barspace = 10;	
	vector<Graph_lib::Rectangle*> rects;	
	for(int i=0; i<cat_sales.size(); i++){
		baroffset_y = 50;
		for(int j=0; j<cat_sales[i].size(); j++){
			//cout << baroffset_x+i*(barwidth+barspace) << " " << baroffset_y << " " <<  
			int curroffset = (int) (barmaxheight*cat_sales[i][j].percent/100);
			if(curroffset==0) {curroffset=1;}
			Graph_lib::Rectangle *rect;
			rect = new Graph_lib::Rectangle(Point(baroffset_x+i*(barwidth+barspace),baroffset_y), 
				barwidth, curroffset);
			baroffset_y += curroffset;
			rect->set_fill_color(get_color(cat_sales[i][j].cat_id));     // color the inside of the rectangle
			rect->set_style(Line_style(Line_style::dash,0));
			rects.push_back(rect);
		}		
	}

	vector<string> t(12);
	t[0] = "Jan";
	t[1] = "Feb";
	t[2] = "Mar";
	t[3] = "Apr";
	t[4] = "May";
	t[5] = "Jun";
	t[6] = "Jul";
	t[7] = "Aug";
	t[8] = "Sep";
	t[9] = "Oct";
	t[10] = "Nov";
	t[11] = "Dec";

	vector<Text*> txtMo(12);
	for(int i=0; i<t.size(); i++){
		txtMo[i] = new Text(Point(baroffset_x+i*(barwidth+barspace), barmaxheight + 90),t[i].c_str());
	}

	vector<Graph_lib::Rectangle*> legends;
	vector<Text*> txtLegend;
	for(int i=0; i<m.get_cats().size(); i++){
		Graph_lib::Rectangle *rect;
		rect = new Graph_lib::Rectangle(Point(baroffset_x+50,barmaxheight+120+i*30),15,15);
		rect->set_fill_color(get_color(m.get_cats()[i].getCatId()));
		stringstream str;
		str<<m.get_cats()[i].getCatId();
		
//		char str[10];
//		itoa(m.get_cats()[i].getCatId(),str,10);
		txtLegend.push_back(new Text(Point(baroffset_x+75,barmaxheight+130+i*30),str.str()));
		legends.push_back(rect);
	}
	
	for(int i=0; i<rects.size(); i++){		
		cat_box.attach(*rects[i]);
	}
	for(int i=0; i<txtMo.size(); i++){		
		cat_box.attach(*txtMo[i]);
	}
	for(int i=0; i<legends.size(); i++){		
		cat_box.attach(*legends[i]);
	}
	for(int i=0; i<txtLegend.size(); i++){		
		cat_box.attach(*txtLegend[i]);
	}
	wait_for_menu_bar_click();	
	
	for(int i=0; i<rects.size(); i++){
		cat_box.detach(*rects[i]);
	}
	for(int i=0; i<txtMo.size(); i++){		
		cat_box.detach(*txtMo[i]);
	}
	for(int i=0; i<legends.size(); i++){		
		cat_box.detach(*legends[i]);
	}
	for(int i=0; i<txtLegend.size(); i++){		
		cat_box.detach(*txtLegend[i]);
	}
	//cat_box.detach(r);
}